package znet

import (
	"errors"
	"gitee.com/hufengjiu/go-zinx/utils"
	"gitee.com/hufengjiu/go-zinx/ziface"
	"log"
)

type Mux struct {
	routers map[uint32]ziface.IRouter
	workers Workers
}

func NewMux(workers Workers) *Mux {
	return &Mux{
		routers: make(map[uint32]ziface.IRouter),
		workers: workers,
	}
}

func (mux *Mux) Handle(r ziface.IRequest) error {
	router, ok := mux.routers[r.GetMsgId()]
	if !ok {
		return errors.New("not found router")
	}
	router.PreHandle(r)
	router.Handle(r)
	router.PostHandle(r)
	return nil
}

func (mux *Mux) AddRouter(msgId uint32, router ziface.IRouter) {
	mux.routers[msgId] = router
}

func (mux *Mux) StartWorkers() {
	for i, _ := range mux.workers {
		mux.workers[i] = make(chan ziface.IRequest, 1024)
		go func(worker Worker, i int) {
			log.Printf("worker %d start...", i)
			for {
				select {
				case req := <-worker:
					log.Printf("--> packet handle worker %d id %d data %s", i, req.GetMsgId(), req.GetData())
					err := mux.Handle(req)
					if err != nil {
						log.Printf("handle pack err %v", err)
					}
				}
			}
		}(mux.workers[i], i)
	}
}

func (mux *Mux) PushToWorker(req ziface.IRequest) {
	//mux.workers[crc32.ChecksumIEEE(req.GetData()) % utils.GlobalConf.WorkersSize] <- req
	mux.workers[req.GetConnection().GetConnId()%utils.GlobalConf.WorkersSize] <- req
}
